﻿using System;
using System.Threading;
using MDF.Worker.Threading.ThreadPools;
using MDF.Worker.Threading.ThreadPools.TaskItems;
using MDF.Worker.Threading.ThreadPools.TaskQueueControllers;
using MDF.Worker.Threading.ThreadPools.TaskQueues;
using System.Collections.Generic;
using MDF.Logger.Managements;
using MDF.Logger.Interfaces;

namespace MDF.Worker.Threading
{
    /// <summary>
    /// Object to control concurency thread 
    /// Author: Duc Ngo
    /// </summary>
    public class ThreadControl
    {
        public delegate void onAddTaskHandeler(ITask taskAdded);
        public static event onAddTaskHandeler onTaskAdded = null;
        /// <summary>
        /// Logger for ThreadControl
        /// </summary>
        private static ILog m_log = LogManager.GetInstance();
        /// <summary>
        /// Multithread
        /// </summary>
        private static IExtendedThreadPool _threadPool;
        /// <summary>
        /// List of task
        /// </summary>
        public static List<ITask> m_lstTask = new List<ITask>();
        /// <summary>
        /// Task index
        /// </summary>
        private static int m_iTaskIndex = 0;
        /// <summary>
        /// Dont allow create default constructor
        /// </summary>
        private ThreadControl()
        {
            if (_threadPool == null)
            {
                m_log.Info("ThreadControl: Constructor default");
                _threadPool = new ExtendedThreadPool.Builder
                {
                    TaskQueueController = new DefaultTaskQueueController(new PriorityTaskQueue())
                }.Build();
                m_log.Info("ThreadControl: Started");
            }
        }
        /// <summary>
        /// Add a task ti Queue
        /// </summary>
        /// <param name="task">Task with type SampleTask</param>
        public static void AddTasks(ITask task)
        {
            //if (task.GetType().Namespace.IndexOf("FAP") != 0 || task.GetType().Namespace == null)
            //{
            //    m_log.Error("The task was block.");
            //    throw new Exception("The task was block");
            //}
            if (_threadPool == null)
            {
                m_log.Info("AddTasks: Constructor default");
                _threadPool = new ExtendedThreadPool.Builder
                {
                    TaskQueueController = new DefaultTaskQueueController(new PriorityTaskQueue())
                }.Build();
                m_log.Info("AddTasks: ThreadControl: Started");
            }
            if (string.IsNullOrEmpty(task.TaskName))
            {
                //task.TaskName = task.GetType().Name;
                m_log.Error("Task Name is not empty.");
                throw new Exception("Task Name is not empty.");
            }
            if (m_lstTask.Exists(m => m.TaskName == task.TaskName))
                return;
            //if (task.onFinished == null)
            //{
            //    m_log.Error("Function onFisnished not implement yet.");
            //    throw new Exception("Function onFisnished not implement.");
            //}
            //if (task.onError == null)
            //{
            //    m_log.Error("Function onError not implement yet.");
            //    throw new Exception("Function onError not implement.");
            //}
            task.TaskIndex = m_iTaskIndex;
            if (onTaskAdded != null)
                onTaskAdded(task);
            m_lstTask.Add(task);
            _threadPool.AddTask(task, task.Priority);
            m_log.Info("Addded thread: " + m_iTaskIndex);
            m_iTaskIndex++;
        }
    }

}
